%BEGIN COPYPASTE EL INFORME DEL INFO
\documentclass[10pt, a4paper,english,spanish]{article}
\usepackage{subfig}

\parindent=20pt
\parskip=8pt
\usepackage[width=15.5cm, left=3cm, top=2.5cm, height= 24.5cm]{geometry}

\usepackage{ccfonts,eulervm} 
\usepackage[T1]{fontenc}
\usepackage{epigraph}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{fancyhdr}
\usepackage[activeacute, spanish]{babel}
\usepackage[utf8x]{inputenc}
\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{afterpage}
\usepackage{caratula}
\usepackage{url}
\usepackage{color}
\usepackage{textcomp}
\usepackage{fancyhdr}
\usepackage{listings}
\usepackage{ulem}
\usepackage{moreverb} 

\floatname{algorithm}{Algoritmo}

\newtheorem{theorem}{Teorema}[section]
\newtheorem{lemma}[theorem]{Lema}
\newtheorem{proposition}[theorem]{Proposici\'on}
\newtheorem{corollary}[theorem]{Corolario}

\newcommand{\Var}{\textbf{var }}
\newcommand{\True}{\textbf{true }}
\newcommand{\False}{\textbf{false }}
\newcommand{\Break}{\textbf{break }}
\newcommand{\Continue}{\textbf{continue }}
\newcommand{\Param}{\textbf{param }}

\newenvironment{proof}[1][Demostraci\'on]{\begin{trivlist}
\item[\hskip \labelsep {\bfseries #1}]}{\end{trivlist}}
\newenvironment{definition}[1][Definici\'on]{\begin{trivlist}
\item[\hskip \labelsep {\bfseries #1}]}{\end{trivlist}}
\newenvironment{example}[1][Ejemplo]{\begin{trivlist}
\item[\hskip \labelsep {\bfseries #1}]}{\end{trivlist}}
\newenvironment{remark}[1][Observaci\'on]{\begin{trivlist}
\item[\hskip \labelsep {\bfseries #1}]}{\end{trivlist}}

\newcommand{\qed}{\nobreak \ifvmode \relax \else
      \ifdim\lastskip<1.5em \hskip-\lastskip
      \hskip1.5em plus0em minus0.5em \fi \nobreak
      \vrule height0.75em width0.5em depth0.25em\fi}

\parindent 0em
\algrenewcommand{\algorithmiccomment}[1]{//\textit{#1} }

\pagestyle{fancy}
\thispagestyle{fancy}
\addtolength{\headheight}{1pt}
\lhead{PLP - TP3}
\rhead{Grupo $\lambda$-team}
\cfoot{\thepage}
\renewcommand{\footrulewidth}{0.4pt}
\newcommand{\hblacksquare}{\hfill \blacksquare}
%FIN COPYPASTE EL INFORME DEL INFO

\newenvironment{source}[0] 
        {\scriptsize\obeylines\verbatimtab} 
        {\endtrivlist\normalsize} 

\begin{document}

\materia{Paradigmas de Lenguajes de Programación}
\submateria{Primer Cuatrim\'estre de 2013}
\titulo{Trabajo Pr\'actico 3}
\subtitulo{Informe}
\grupo{Grupo $\lambda$-team}
\integrante{Juli\'an Sackmann}{540/09}{jsackmann@gmail.com}
\integrante{Mat\'ias Bender}{366/10}{matibender@gmail.com}
\integrante{Juan Pablo Darago}{272/10}{jpdarago@gmail.com}

\maketitle
\pagebreak

\tableofcontents
\pagebreak

\section{Implementaci\'on}

\subsection{Polinomio}

\begin{source}
Object subclass: #Polinomio
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!

* otroPolinomio
	"Devuelve el polinomio resultado de sumar un polinomio con otro"
	^(MultiplicacionPolinomios multiplicar: self con: otroPolinomio).! !

+ otroPolinomio
	"Devuelve el polinomio resultado de sumar un polinomio con otro"
	^(SumaPolinomios sumar: self con: otroPolinomio).! !

= otroPolinomio
	^(self coeficientes) = (otroPolinomio coeficientes)! !

coeficientes
	"Diccionario con grados como clave y coeficientes como valores"
	self subclassResponsibility.! !

evaluar: unValor
	"El objeto que representa el resultado de evaluar el polinomio asignado unValor a la variable"
	self subclassResponsibility.! !

grado
	"Retorna el grado del polinomio"
	self subclassResponsibility.! !
\end{source}

\subsection{Constante}

\begin{source}
﻿Polinomio subclass: #Constante
	instanceVariableNames: 'valor'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!

coeficientes
	^(Dictionary newFromPairs: { 0. valor })! !

evaluar: unValor
	^valor! !

grado
	^0! !

inicializar: unValor
	valor := unValor.! !

puedeEvaluarseCon: unValor
	^true.! !

Constante class
	instanceVariableNames: ''!

new: unValor
	| res |
	res := Constante new.
	res inicializar: unValor.
	^res! !

\end{source}

\subsection{Variable}

\begin{source}
Polinomio subclass: #Variable
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!

coeficientes
	^(Dictionary newFromPairs: { 1. 1 })! !

evaluar: unValor
	^unValor! !

grado
	^1! !

puedeEvaluarseCon
	 ^true! !

puedeEvaluarseCon: unValor
	 ^true! !
\end{source}

\subsection{Suma de Polinomios}

\begin{source}
﻿Polinomio subclass: #SumaPolinomios
	instanceVariableNames: 'primero segundo'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!

coeficientes
	| coefsPrim coefsSeg resultado |
	
	coefsPrim := primero coeficientes.
	coefsSeg := segundo coeficientes.
	
	resultado := Dictionary new.
	coefsSeg keysAndValuesDo: [ 
		:grado :coeficiente |
			resultado at: grado put: coeficiente.
	].
	coefsPrim keysAndValuesDo: [ 
		:grado :coeficiente |
			resultado at: grado put: 
				(coefsSeg at: grado 
					ifPresent: [ :v | v + coeficiente ] 
					ifAbsent: [ coeficiente ]).
	 ].

	^resultado.! !

evaluar: unValor
	(self puedeEvaluarseCon: unValor) ifFalse: [   ^'AlguienNoEntiende'  ].
	^(primero evaluar: unValor) + (segundo evaluar: unValor)! !

grado
	^((primero grado) max: (segundo grado))! !

puedeEvaluarseCon: unValor
	^((primero evaluar: unValor) respondsTo: #+)! !

sumar: prim con: seg
	primero := prim. 
	segundo := seg.
	^self! !

SumaPolinomios class
	instanceVariableNames: ''!

sumar: prim con: seg
	"Construye un nuevo polinomio dados los dos polinomios a sumar"
	^((SumaPolinomios new) sumar: prim con: seg)! !
\end{source}

\subsection{MultiplicacionPolinomios}

\begin{source}
﻿Polinomio subclass: #MultiplicacionPolinomios
	instanceVariableNames: 'primero segundo'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!

coeficientes
	| coefsPrim coefsSeg resultado |
	
	coefsPrim := primero coeficientes.
	coefsSeg := segundo coeficientes.
	
	resultado := Dictionary new.
	coefsPrim keysAndValuesDo: [ :gradoPrim :coeficientePrim |
		coefsSeg keysAndValuesDo: [ :gradoSeg :coeficienteSeg |
			| grado coeficiente |
			
			grado := gradoPrim + gradoSeg.
			coeficiente := coeficientePrim * coeficienteSeg.
			resultado at: grado put: 
				(resultado at: grado 	
					ifPresent: [: v | coeficiente + v] 
					ifAbsent:  [coeficiente ]).
	 	].
	 ].
	 ^resultado! !

evaluar: unValor
	(self puedeEvaluarseCon: unValor) ifFalse: [   ^'AlguienNoEntiende'  ].
	^(primero evaluar: unValor) * (segundo evaluar: unValor)! !

grado
	^(primero grado) + (segundo grado)! !

multiplicar: prim con: seg
	"Construye un nuevo polinomio dados los dos polinomios a multiplicar"
	primero := prim. 
	segundo := seg.
	^self! !

puedeEvaluarseCon: unValor
	^((primero evaluar: unValor) respondsTo: #*)! !

MultiplicacionPolinomios class
	instanceVariableNames: ''!

multiplicar: prim con: seg
	"Construye un nuevo polinomio dados los dos polinomios a multiplicar"
	^((MultiplicacionPolinomios new) multiplicar: prim con: seg)! !
\end{source}

\subsection{Tests}

\begin{source}
TestCase subclass: #PolinomioTest
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'PLP-Tp3'!
A PolinomioTest is a test class for testing the behavior of Polinomio!

polinomio1
	^(Variable new) + (Constante new: 69)! !

polinomio2
	 ^(Constante new: 69)! !

polinomio3
	^((Variable new) * (Variable new) * (Variable new))! !

polinomio4
	 ^((((Variable new) * (Variable new)) + (Constante new: 7)) * (Variable new)) + (Constante new: 90)! !

polinomio5
	^ (Variable new) * ((Constante new: 0) + ((Variable new) * (Variable new))) ! !

polinomio6
	^(Variable new)! !

polinomio7
	^(Variable new) * (Variable new)! !

polinomio8
	^(Variable new)*(Variable new)*(Variable new)*(Variable new)*(Variable new)*(Variable new)! !


testCoeficientes
	"Test de coeficientes de polinomios"

		|  polinomio1 polinomio4 |
	
	polinomio1 := self polinomio1.
	polinomio4 := self polinomio4.
	
	self assert: ((polinomio1 coeficientes at: 0) = 69).
	self assert: ((polinomio1 coeficientes at: 1) = 1).
	self assert: ((polinomio4 coeficientes at: 0) = 90).
	self assert: ((polinomio4 coeficientes at: 1) = 7).
	self assert: ((polinomio4 coeficientes at: 3) = 1).
	self assert: ( (polinomio4 coeficientes includesKey: 2) not).
	self assert: ( (polinomio4 coeficientes includesKey: 4) not).
	self assert: ( (polinomio4 coeficientes size) = 3).! !

testEvaluar
	"Test de evaluación de polinomios"

	| polinomio1 polinomio2 polinomio3 polinomio4 |
	
	polinomio1 := self polinomio1.
	polinomio2 := self polinomio2.
	polinomio3 := self polinomio3.
	polinomio4 := self polinomio4.
	
	self assert: ( (polinomio1 evaluar:  11) = 80).
	
	self assert: ( (polinomio2 evaluar: nil) = 69).
	self assert: ( (polinomio2 evaluar: 23) = 69).
	
	self assert: ( (polinomio3 evaluar: 3) = 27).
	
	self assert: ( (polinomio4 evaluar: 2) = 112).! !

testGrado

	| polinomio1 polinomio2 polinomio3 polinomio4 |
	
	polinomio1 := self polinomio1.
	polinomio2 := self polinomio2.
	polinomio3 := self polinomio3.
	polinomio4 := self polinomio4.
	
	self assert: (polinomio1 grado = 1).
	self assert: (polinomio2 grado = 0).
	self assert: (polinomio3 grado = 3).
	self assert: (polinomio4 grado = 3).! !

testIgualdad
	"Test de igualdad de polinomios"

	| polinomio1 polinomio2 |
	
	polinomio1 := self polinomio1.
	polinomio2 := self polinomio2.
	
	self assert: ( polinomio1 = polinomio1 ).
	self assert: ( (polinomio1 = polinomio2) not ).! !

testMetaprogramacion
	| polinomio |
	
	polinomio := self polinomio1 .
	self assert: ( (polinomio evaluar: (PolinomioTest new)  ) = 'AlguienNoEntiende' ).
	self assert:( (polinomio evaluar: '12') = 81). 
! !

testMultiplicacion
	"Test de multiplicacion de polinomios"

	| polinomio3 polinomio6 polinomio7 |
	
	polinomio3 := self polinomio3.
	polinomio6 := self polinomio6.
	polinomio7 := self polinomio7.
	
	self assert: (polinomio6 * polinomio7 = polinomio3).
	self assert: (polinomio7 * polinomio6 = polinomio3).! !

testSuma
	"Test suma de polinomios"

	| polinomio1 polinomio2 polinomio6|
	
	polinomio1 := self polinomio1.
	polinomio2 := self polinomio2.
	polinomio6 := self polinomio6.
	
	self assert: (polinomio2 + polinomio6 = polinomio1).
	self assert: (polinomio6 + polinomio2 = polinomio1).
	! !

testSupremo
	"El test supremo de los polinomios"

	| polinomio3 polinomio6 polinomio7 polinomio8 |
	
	polinomio3 := self polinomio3.
	polinomio6 := self polinomio6.
	polinomio7 := self polinomio7.
	polinomio8 := self polinomio8.
		
	self assert: ( (polinomio6 evaluar: polinomio7) = polinomio7).
	
	self assert: ( (polinomio3 evaluar: polinomio6) = polinomio3).
	
	self assert: ( (polinomio3 evaluar: polinomio7) = polinomio8). 
	
	self assert: ( (polinomio7 evaluar: polinomio3) = polinomio8). ! !

\end{source}

\end{document}
